<script setup>
import "@wangeditor/editor/dist/css/style.css";
import { ref, shallowRef, onBeforeUnmount, nextTick, watch } from "vue";
import { Editor, Toolbar } from "@wangeditor/editor-for-vue";
import { DomEditor } from "@wangeditor/editor";
import { useVModel } from "@vueuse/core";
import utils from "../../common/utils/utils";
import store from "../../store/index";
import { Menu as ContinuationButtonMenu } from "./ai-plugins/continuation";

const props = defineProps({
  content: {
    type: String,
    default: "",
  },
  placeholder: {
    type: String,
    default: "请输入内容...",
  },
  editorBgColor: {
    type: String,
    default: "#fff",
  },
  showTitle: {
    type: Boolean,
    default: false,
  },
  titlePlaceholder: {
    type: String,
    default: "文案标题...",
  },
  title: {
    type: String,
    default: "",
  },
});

const editorRef = shallowRef();
const emit = defineEmits(["update:content", "change", "update:title"]);
const vContent = useVModel(props, "content", emit);
const vTitle = useVModel(props, "title", emit);
const toolbarConfig = {
  toolbarKeys: [
    "bold",
    "italic",
    "underline",
    "through",
    "uploadImage",
    "|",
    "ai-expand-writer",
    "ai-rewriter",
    "ai-abbreviation",
    "ai-continuation",
    "|",
    "undo",
    "redo",
    "|",
    "ai-export",
  ],
};
const editorConfig = {
  placeholder: props.placeholder,
  hoverbarKeys: {
    text: {
      menuKeys: [
        "bold",
        "italic",
        "underline",
        "through",
        "insertLink",
        "color",
        "ai-expand-writer",
        "ai-rewriter",
        "ai-abbreviation",
        "ai-continuation",
      ],
    },
  },
  MENU_CONF: {
    uploadImage: {
      server: utils.imgAction,
      fieldName: "image",
      headers: {
        "org-token": store.getters.token,
      },
      meta: {
        dir: "work_ai",
      },
      customInsert(res, insertFn) {
        insertFn(res.data.fileUrl);
      },
    },
  },
};

const mode = ref("default");
const getContent = () => {
  return vContent.value;
};

const setContent = (content) => {
  vContent.value = content;
};

watch(vContent, (val) => {
  emit("change", val);
});

// 组件销毁时，也及时销毁编辑器
onBeforeUnmount(() => {
  const editor = editorRef.value;
  if (editor == null) return;
  editor.destroy();
});

const handleCreated = (editor) => {
  editorRef.value = editor;

  nextTick(() => {
    const toolbar = DomEditor.getToolbar(editor);
    console.log(
      toolbar.getConfig().toolbarKeys,
      editor.getConfig().hoverbarKeys
    );
  });
};

const onContinuationWrite = () => {
  const editor = editorRef.value;

  if (!editor.isFocused()) {
    editor.focus(true);
  }

  const menu = new ContinuationButtonMenu();
  menu.exec(editor);
};

const writeFinish = () => {
  const editor = editorRef.value;
  editor.blur();

  nextTick(() => {
    editor.focus(true);
  });
};

defineExpose({
  setContent,
  getContent,
  writeFinish,
});
</script>

<template>
  <div
    class="scene-editor h-full relative"
    v-bind="$attrs"
    :style="`--scene-editor-bg-color: ${editorBgColor};`"
  >
    <Toolbar
      style="border-bottom: 1px solid #ccc"
      :editor="editorRef"
      :defaultConfig="toolbarConfig"
      :mode="mode"
    />
    <div id="title-container" v-if="showTitle">
      <a-input v-model:value="vTitle" :placeholder="titlePlaceholder" />
    </div>
    <Editor
      style="height: calc(100% - 100px); overflow-y: hidden"
      v-model="vContent"
      :defaultConfig="editorConfig"
      :mode="mode"
      @onCreated="handleCreated"
    />
    <a-button
      shape="round"
      style="
        position: absolute;
        bottom: 20px;
        left: 50%;
        color: var(--ss-primary-color);
        border-color: var(--ss-primary-color);
      "
      @click="onContinuationWrite"
      >续写</a-button
    >
  </div>
</template>

<style lang="less" scoped>
.scene-editor :deep(.w-e-drop-panel) {
  min-width: auto;

  .panel-list {
    width: 80px;

    .panel-item {
      height: 30px;
      line-height: 30px;
      cursor: pointer;

      &:hover {
        background-color: #f6f6f7;
      }
    }
  }
}

.scene-editor :deep(.w-e-text-container) {
  background-color: var(--scene-editor-bg-color);
}

#title-container {
  padding: 10px 10px;
  border-bottom: 1px solid #e8e8e8;
  background-color: var(--scene-editor-bg-color);

  input {
    font-size: 30px;
    border: 0;
    outline: none;
    width: 100%;
    line-height: 1;
    background-color: var(--scene-editor-bg-color);
  }
}
:deep(.ant-input:focus) {
  border-right-width: unset !important;
  box-shadow: unset !important;
}
</style>
